

#define NO_Debug_Normals
#define SPLINE

using System;
using System.Collections.Generic;
using System.Text;
using IrrlichtNETCP;
using IrrlichtNETCP.Inheritable;


namespace Tubes {
    public class ModelSceneNode : ISceneNode {
        Vertex3D[][] vertices;
        ushort[][] indici;

        Box3D Box = new Box3D();
        Material material = new Material();
        SceneManager _mgr;
        VideoDriver _driver;

        public ModelSceneNode(SceneNode parent, int id, SceneManager smgr, csMake3D.core.Model m)
            : base(parent, smgr, id) {
            _mgr = smgr;
            _driver = _mgr.VideoDriver;

            this.vertices = new Vertex3D[m.Count][];
            this.indici = new ushort[m.Count][];

            for (int i = 0; i < m.Count; i++) {
                vertices[i] = new Vertex3D[m[i].vertices.Length];

                for (int v = 0; v < m[i].vertices.Length; v++) {

                    csMake3D.core.Vertex v3d = m[i].vertices[v];
                    vertices[i][v] = new Vertex3D(new Vector3D(v3d.Pos.X, v3d.Pos.Y, v3d.Pos.Z),
                                                  new Vector3D(v3d.Normal.X, v3d.Normal.Y, v3d.Normal.Z),
                                                  new Color(v3d.Color.A, v3d.Color.R, v3d.Color.G, v3d.Color.B),
                                                  new Vector2D(v3d.TCoord.X, v3d.TCoord.Y));                    
                    Box.AddInternalPoint(vertices[i][v].Position);

                }

                indici[i] = new ushort[m[i].indices.Length];
                Array.Copy(m[i].indices, indici[i], indici[i].Length);
            }

            material.Lighting = false;
            material.NormalizeNormals = false;
            material.Shininess = 0f;
            material.TrilinearFilter = true;
            material.GouraudShading = true;
            material.MaterialType = MaterialType.Solid;




        }

        public override void Render() {
            _driver.SetMaterial(material);
            _driver.SetTransform(TransformationState.World, AbsoluteTransformation);

            if (vertices != null) {
                for (int i = 0; i < vertices.Length; i++)
                    _driver.DrawIndexedTriangleList(vertices[i], vertices[i].Length, indici[i], indici[i].Length / 3);
            }

#if Debug_Normals
            for (int i = 0; i < vertices.Length; i++) {
                for (int j = 0; j < vertices[i].Length; j++) {
                    vertices[i][j].Normal.Normalize();
                    Line3D line = new Line3D(vertices[i][j].Position, vertices[i][j].Position + vertices[i][j].Normal * 0.8f);
                    _driver.Draw3DLine(line, new Color(2255, 200, 200, 200));
                }
            }
#endif


        }

        public override void OnRegisterSceneNode() {
            if (Visible) {
                _mgr.RegisterNodeForRendering(this, SceneNodeRenderPass.Light);               
            }
            base.OnRegisterSceneNode();
        }

        public override Box3D BoundingBox {
            get {
                return Box;
            }
        }

        public override uint MaterialCount {
            get {
                return 1;
            }
        }

        public override Material GetMaterial(int i) {
            return material;
        }
    }

}